function Demo(canvas,options){
	this.options = options;
	this.renderFlag = true;
	//init
	this.canvas = canvas;
	this.engine = new BABYLON.Engine(this.canvas, false, { preserveDrawingBuffer: true, stencil: true,  disableWebGL2Support: false})
	this.scene = new BABYLON.Scene(this.engine);
	//custom loading
	// if(this.options.customLoading){
	// 	this.engine.loadingScreen = this.options.customLoading();
	// 	this.engine.displayLoadingUI();
	// }
	//default init
	this.selectMesh;
	this.AssetsManager;
	this.AssetsManagerArr = [];
	this.hideList = [];
	this.clipX;
	this.clipY;
	this.clipZ;
	
	
	//Variables
	this.colorTeal = new BABYLON.Color3(1, 0, 0);	//选中高光
	
	this.scene.createDefaultLight(true, true, true);
	let defaultLight =  this.scene.getLightByName('default light')
	defaultLight.intensity = 1;
	this.camera();
	this.HighlightLayer();
	this.addLight();
	this.bindEvent();
	if(this.options.debug){
		this.scene.debugLayer.show({ showExplorer: true });
	}
	
	
	//解析options
	this.analysisOptions() 
	
	//render
	this.render();
	// this.showAxis(300)
	// window.addEventListener("resize", ()=>{
	// 	 this.engine.resize();
	// });
}

// Demo.prototype.customLoading = function(){
// 	let $this = this;
// 	function customLoadingScreen() {
// 		console.log("customLoadingScreen creation")
// 	}
// 	customLoadingScreen.prototype.displayLoadingUI = function () {
// 		console.log("customLoadingScreen loading")
// 		// loadingScreenDiv.innerHTML = "loading";
// 	};
// 	customLoadingScreen.prototype.hideLoadingUI = function () {
// 		console.log("customLoadingScreen loaded")
// 		// loadingScreenDiv.style.display = "none";
// 	};
// 	return new customLoadingScreen();
// }
Demo.prototype.addLight = function(){
	// this.light = new BABYLON.DirectionalLight("light1", new BABYLON.Vector3(0,0,0), this.scene);
	// this.light.intensity = 1;
	// let light = new BABYLON.DirectionalLight('DirectionalLight',new BABYLON.Vector3(0,0,0),this.scene);
	// light.intensity = 2.5;
	// light.diffuse = new BABYLON.Color3(1, 1, 1);
	// light.specular = new BABYLON.Color3(1, 1, 1);
	// light.groundColor = new BABYLON.Color3(0, 0, 0);
	// light.position.z = 500;
}

Demo.prototype.showAxis = function(size){
	let $this = this;
	var makeTextPlane = function (text, color, size) {
		var dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", 50, $this.scene, true);
		dynamicTexture.hasAlpha = true;
		dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color, "transparent", true);
		var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, $this.scene, true);
		plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", $this.scene);
		plane.material.backFaceCulling = false;
		plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
		plane.material.diffuseTexture = dynamicTexture;
		return plane;
	};
	
	var axisX = BABYLON.Mesh.CreateLines("axisX", [
		new BABYLON.Vector3.Zero(), new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, 0.05 * size, 0),
		new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, -0.05 * size, 0)
	], $this.scene);
	axisX.color = new BABYLON.Color3(1, 0, 0);
	var xChar = makeTextPlane("X", "red", size / 10);
	xChar.position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0);
	var axisY = BABYLON.Mesh.CreateLines("axisY", [
		new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3(-0.05 * size, size * 0.95, 0),
		new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3(0.05 * size, size * 0.95, 0)
	], $this.scene);
	axisY.color = new BABYLON.Color3(0, 1, 0);
	var yChar = makeTextPlane("Y", "green", size / 10);
	yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
	var axisZ = BABYLON.Mesh.CreateLines("axisZ", [
		new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3(0, -0.05 * size, size * 0.95),
		new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3(0, 0.05 * size, size * 0.95)
	], $this.scene);
	axisZ.color = new BABYLON.Color3(0, 0, 1);
	var zChar = makeTextPlane("Z", "blue", size / 10);
	zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
	
}


Demo.prototype.analysisOptions = function(){
	if(this.options){
		let keys = Object.keys(this.options);
		
		//资源加载
		if(keys.includes('AssetsManager')){
			let item = this.options['AssetsManager'];
			if(item.length > 0){
				this.AssetsManager = new BABYLON.AssetsManager(this.scene);
				for(let i=0;i<item.length;i++){
					let once = item[i];
					let file = once.match(/.[^/]*$/)[0].substr(1);
					let path = once.replace(file,'/');
					let task = this.AssetsManager.addMeshTask(file, "",path, file)
				}
				this.AssetsManager.load();
				this.AssetsManager.onFinish = (task)=>{
					if(this.options.AssetsManagerLoaded) this.options.AssetsManagerLoaded(task);
					//天空盒
					if(keys.includes('sky') && this.options.sky != ''){
						this.sky();
					}
					//流水
					if(keys.includes('waters') && this.options.waters.length){
						if(this.options.waters.length) this.setWater();
					}
					task.forEach((t)=>{
						this.AssetsManagerArr = this.AssetsManagerArr.concat(t.loadedMeshes)
					})
					if(this.options.loaded) this.options.loaded(this.AssetsManagerArr)
					// this.camera.setTarget(new BABYLON.Vector3(170,80,0))
					// console.log(this.AssetsManagerArr)
					// debugger;
					// this.render();
					// this.renderFlag = false;
				}
			}
		}
		if(keys.includes('clip') && this.options['clip'].length > 0){
			this.clippingX();
			this.clippingY();
			this.clippingZ();
			console.log(this.clipX)
			this.scene.onBeforeRenderObservable.add(() => {
				// console.log(this.clipX)
				if(this.clipX) this.scene.clipPlane = this.clipX;
				if(this.clipY) this.scene.clipPlane2 = this.clipY;
				if(this.clipZ) this.scene.clipPlane3 = this.clipZ;
			});
		
			this.scene.onAfterRenderObservable.add(() => {
				this.scene.clipPlane = null;
				this.scene.clipPlane2 = null;
				this.scene.clipPlane3 = null;
			});
			
		}
	}
}

Demo.prototype.clippingX = function(){
	this.clipX = new BABYLON.Plane(1, 0,0);
}

Demo.prototype.clippingY = function(){
	this.clipY = new BABYLON.Plane(0, 1,0);
}

Demo.prototype.clippingZ = function(){
	this.clipZ = new BABYLON.Plane(0, 0,1);
}

Demo.prototype.setWater = function(){
	this.options.waters.forEach((item,index)=>{
		var water = new BABYLON.WaterMaterial("water", this.scene);
		water.backFaceCulling = true;
		water.bumpTexture = new BABYLON.Texture("public/images/waterbump.png", this.scene);
		water.rewindFocus = 1; //风速
		water.windDirection.x = .2; //风向
		water.windDirection.y = .3; //风向
		water.waveHeight = .8;  //波浪高度
		water.bumpHeight = .5;	//水纹理高度
		water.waveLength = 7;	//波浪长度
		water.waveSpeed = 1;	//波浪运行速度
		water.waterColor = new BABYLON.Color3(0,0,.5); //水的颜色
		water.colorBlendFactor = 0;
		
		if(item.addToRenderListId.length > 0){
			item.addToRenderListId.forEach ((renderOnce)=>{
				water.addToRenderList(this.findMeshById(renderOnce));
			})
		}
		if(this.skybox){
			water.addToRenderList(this.skybox);
		}
		this.findMeshById(item.id).material = water;
	})
}
Demo.prototype.sky = function(){
	// Skybox
	var skybox = BABYLON.Mesh.CreateBox("skyBox", 5000.0, this.scene);
	var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", this.scene);
	skyboxMaterial.backFaceCulling = false;
	skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture(this.options.sky, this.scene);
	skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
	skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
	skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
	skyboxMaterial.disableLighting = true;
	skybox.material = skyboxMaterial;
	this.skybox = skybox;
}

Demo.prototype.camera = function(){
	this.camera =   new BABYLON.ArcRotateCamera("gloCamera",0, Math.PI/2, 800, new BABYLON.Vector3(170,80,0), this.scene,0);
	this.camera.lowerRadiusLimit = 0;
	this.camera.upperRadiusLimit = 500;
	// this.camera.lowerBetaLimit = 0.1;
	// this.camera.upperBetaLimit = Math.PI-0.1;		
	// this.camera.lowerAlphaLimit = (-Math.PI)+0.1;
	// this.camera.upperAlphaLimit = (Math.PI)-0.1;		
	this.camera.panningSensibility = 15;  //右键平移。定义输入的平移灵敏度。（相机平移速度）越大相对移动距离越慢
	this.camera.panningInertia = 0.2; //相机平移过程中使用的惯性值(阻尼系数)。越大相机平移后减速越快
	this.camera.wheelPrecision = 1.0;//相机缩放的速度。值越大，缩放速度越慢。
	this.camera.zoomingSensibility = 25;//定义输入的缩放灵敏度。
	//this.camera.attachControl(canvas, true, true);	
	// this.camera.useFramingBehavior = false;
	// this.camera.allowUpsideDown = false;			
	this.scene.activeCamera = this.camera;
	this.camera.attachControl(this.canvas, true, true);
	// this.camera.onViewMatrixChangedObservable(()=>{
	// 	this.render();
	// })
}

Demo.prototype.HighlightLayer = function(){
	// let gloEnvHelper = this.scene.createDefaultEnvironment(); 
	let hll01 = new BABYLON.HighlightLayer("hll01", this.scene,{renderingGroupId:1});
	hll01.blurHorizontalSize = 0.25;  //高光层大小水平方向      
	hll01.blurVerticalSize = 0.25;	 //高光层大小垂直方向  
	hll01.innerGlow = false;
	// hll01.addExcludedMesh(gloEnvHelper.ground);
	// hll01.addExcludedMesh(gloEnvHelper.skybox);	
	this.hll01 = hll01;
}
Demo.prototype.render = function(){
	this.engine.runRenderLoop(()=>{
	// 	// if(!this.renderFlag) return;
	// 	if (this.scene && this.scene.activeCamera) {
		    this.scene.render();
	// 	}
	});
}
Demo.prototype.Sphere = function(name,segments,diameter,color,position){
	let  _sphere = BABYLON.Mesh.CreateSphere(name,segments,diameter, this.scene);
	let Material = new BABYLON.StandardMaterial(`${name}Material`, this.scene);
	_sphere.position = position || new BABYLON.Vector3.Zero();
	// Material.emissiveColor = color; 
	_sphere.material = Material;
	this.AssetsManagerArr.push(_sphere)
}
Demo.prototype.Ground = function(name,width,height){
	let _group = BABYLON.Mesh.CreateGround(`${name}Group`, {width, height});
}
Demo.prototype.bindEvent = function(){
	this.scene.onPointerObservable.add((pointerInfo) => {
	switch (pointerInfo.type){
		case BABYLON.PointerEventTypes.POINTERDOWN:
			break;
		case BABYLON.PointerEventTypes.POINTERUP:
			break;
		case BABYLON.PointerEventTypes.POINTERMOVE:
			break;		
		case BABYLON.PointerEventTypes.POINTERWHEEL:
			break;
		case BABYLON.PointerEventTypes.POINTERPICK:	//选中
			// if(Object.keys(this.hll01._meshes).length > 1) this.removeAllHll01();
			console.log('pointerInfo.pickInfo.pickedMesh.name',pointerInfo.pickInfo.pickedMesh.name)
			// if(pointerInfo.pickInfo.pickedMesh !== this.selectMesh){
				//先清除以前
				// if(this.selectMesh){
				// 	this.delHll01(this.selectMesh);
				// }
				//添加最新
				// this.setHll01([pointerInfo.pickInfo.pickedMesh]);
				// this.selectMesh = pointerInfo.pickInfo.pickedMesh
				if(this.options.meshClick) this.options.meshClick(pointerInfo.pickInfo.pickedMesh)
			// }else{
				// this.delHll01(this.selectMesh);
				// this.selectMesh = null;
			// }
			break;
		case BABYLON.PointerEventTypes.POINTERTAP:
			if(pointerInfo.pickInfo.pickedMesh === undefined){
			// 	this.delHll01(this.selectMesh);
				this.selctMesh = null;
				// if(this.options.meshClick) this.options.meshClick(this.selectMesh)
			}
			
			console.log("POINTER TAP");
			break;
		case BABYLON.PointerEventTypes.POINTERDOUBLETAP:
			console.log("POINTER DOUBLE-TAP");
			break;
		default:
			break;
	}});
}
Demo.prototype.setHll01 = function(arr){
	arr.forEach((item,index)=>{
		item.renderingGroupId = 1;
		// item.visibility = 1;
		this.hll01.addMesh(item,this.colorTeal)
		
	})
}
Demo.prototype.delHll01 = function(mesh){
	if(this.hll01.hasMesh(mesh) || this.hll01.hasMesh(mesh._sourceMesh)){
		mesh.renderingGroupId = 0;
		// mesh.visibility = .15;
		this.hll01.removeMesh(mesh)
	}
}
Demo.prototype.removeAllHll01 = function(mesh){
	for(let key in this.hll01._meshes){
		let once = this.hll01._meshes[key].mesh
		this.delHll01(once)
	}
}
Demo.prototype.setAlpha = function(alpha){
	if(this.selectMesh){
		this.selectMesh.visibility = alpha
	}
}
Demo.prototype.setVisiblity = function(flag){
	if(this.selectMesh){
		this.selectMesh.isVisible = flag
	}
}
Demo.prototype.setArrVisiblityFalse = function(arr,flag){
	arr.forEach((mesh)=>{
		mesh.isVisible = flag;
	})
}
Demo.prototype.setAllVisiblity = function(flag){
	this.AssetsManagerArr.forEach((item)=>{
		if(item.hasOwnProperty('loadedMeshes')){
			item.loadedMeshes.forEach((item1)=>{
				item1.isVisible = flag
			})
		}else{
			item.isVisible = flag
		}
	})
}

Demo.prototype.setAllAlpha = function(alpha){
	this.AssetsManagerArr.forEach((item)=>{
		if(item.hasOwnProperty('loadedMeshes')){
			item.loadedMeshes.forEach((item1)=>{
				item1.visibility = alpha
			})
		}else{
			item.visibility = alpha
		}
	})
}
Demo.prototype.findMeshByName = function(id){
	return this.scene.getNodeByName(id)
}
Demo.prototype.findMeshByNameAll = function(arr){
	return arr.reduce((a,id)=>{
		a.push(this.scene.getNodeByName(id))
		return a;
	},[])
}
Demo.prototype.findKeywordMesh = function(keyword){
	return this.scene.meshes.filter((item)=>{
		return item.id.includes(keyword)
	})
}
Demo.prototype.removeMesh = function(mesh){
	this.scene.removeMesh(mesh)
}
Demo.prototype.addMesh = function(mesh){
	this.scene.addMesh(mesh)
}
export default Demo;